#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <assert.h>
#include <sstream>
#include <cgi_control.h>
#include <Singleton.h>
#include <memcheck.h>
#include <log.h>
#include <http_decoder.h>
#include <keydic.h>

using namespace std;

HTTP_SVR_NS_BEGIN

int         TCGIControl::_nCgiCount     = 0;
TCGIInfo*   TCGIControl::_stCgiList     = NULL;

struct proxy_mrec {
    int gzippable;
    const char ext[8];
    const char *mime;
    //struct mrec *next;
};

 static struct proxy_mrec proxy_mimetypes[] = {
    { 1, "ai\0",  "application/postscript" },
    { 0, "ace",   "application/octet-stream" },
    { 1, "aif",   "audio/x-aiff" },
    { 1, "aifc",  "audio/x-aiff" },
    { 1, "aiff",  "audio/x-aiff" },
    { 2, "asc",   "text/plain" },
    { 0, "asf",   "video/x-ms-asf" },
    { 1, "au\0",  "audio/basic" },
    { 0, "avi",   "video/x-msvideo" },
    { 1, "bcpio", "application/x-bcpio" },
    { 1, "bin",   "application/octet-stream" },
    { 1, "bmp",   "image/bmp" },
    { 0, "bz2",   "application/x-bzip2" },
    { 0, "cab",   "application/octet-stream" },
    { 1, "cdf",   "application/x-netcdf" },
    { 1, "cgm",   "image/cgm" },
    { 1, "class", "application/octet-stream" },
    { 1, "cpio" , "application/x-cpio" },
    { 1, "cpt",   "application/mac-compactpro" },
    { 0, "cpz",   "application/x-gzip" },
    { 2, "csh",   "application/x-csh" },
    { 2, "css",   "text/css" },
    { 2, "csv",   "text/plain" },
    { 1, "dcr",   "application/x-director" },
    { 1, "dir",   "application/x-director" },
    { 1, "djv",   "image/vnd.djvu" },
    { 1, "djvu",  "image/vnd.djvu" },
    { 1, "dll",   "application/octet-stream" },
    { 1, "dl_",   "application/octet-stream" },
    { 1, "dmg",   "application/octet-stream" },
    { 1, "dms",   "application/octet-stream" },
    { 2, "doc",   "application/msword" },
    { 1, "dtd",   "application/xml-dtd" },
    { 1, "dvi",   "application/x-dvi" },
    { 1, "dxr",   "application/x-director" },
    { 2, "eml",   "message/rfc822" },
    { 1, "eps",   "application/postscript" },
    { 2, "etx",   "text/x-setext" },
    { 1, "exe",   "application/octet-stream" },
    { 1, "ex_",   "application/octet-stream" },
    { 1, "ez\0",  "application/andrew-inset" },
    { 0, "gif",   "image/gif" },
    { 1, "gram",  "application/srgs" },
    { 1, "grxml", "application/srgs+xml" },
    { 1, "gtar",  "application/x-gtar" },
    { 0, "gz\0",  "application/x-gzip" },
    { 1, "hdf",   "application/x-hdf" },
    { 2, "htc",   "text/plain" },
    { 1, "hqx",   "application/mac-binhex40" },
    { 2, "htm",   "text/html" },
    { 2, "html",  "text/html" },
    { 1, "ice",   "x-conference/x-cooltalk" },
    { 2, "ico",   "image/x-icon" },
    { 2, "ics",   "text/calendar" },
    { 1, "ief",   "image/ief" },
    { 2, "ifb",   "text/calendar" },
    { 1, "iges",  "model/iges" },
    { 1, "igs",   "model/iges" },
    { 0, "jpe",   "image/jpeg" },
    { 0, "jpeg",  "image/jpeg" },
    { 0, "jpg",   "image/jpeg" },
    { 2, "js\0",  "application/x-javascript" },
    { 0, "kar",   "audio/midi" },
    { 1, "latex", "application/x-latex" },
    { 0, "lha",   "application/octet-stream" },
    { 0, "lzh",   "application/octet-stream" },
    { 2, "m3u",   "audio/x-mpegurl" },
    { 2, "m4u",   "video/vnd.mpegurl" },
    { 1, "man",   "application/x-troff-man" },
    { 2, "mathml","application/mathml+xml" },
    { 1, "me\0",  "application/x-troff-me" },
    { 1, "mesh",  "model/mesh" },
    { 2, "mht",   "message/rfc822" },
    { 2, "mhtml", "message/rfc822" },
    { 0, "mid",   "audio/midi" },
    { 0, "midi",  "audio/midi" },
    { 1, "mif",   "application/vnd.mif" },
    { 0, "mov",   "video/quicktime" },
    { 0, "movie", "video/x-sgi-movie" },
    { 0, "mp2",   "audio/mpeg" },
    { 0, "mp3",   "audio/mpeg" },
    { 0, "mp4",   "video/mpeg" },
    { 0, "mpe",   "video/mpeg" },
    { 0, "mpeg",  "video/mpeg" },
    { 0, "mpg",   "video/mpeg" },
    { 0, "mpga",  "audio/mpeg" },
    { 1, "ms\0",  "application/x-troff-ms" },
    { 1, "msh",   "model/mesh" },
    { 0, "mxu",   "video/vnd.mpegurl" },
    { 1, "nc\0",  "application/x-netcdf" },
    { 1, "oda",   "application/oda" },
    { 0, "ogg",   "application/ogg" },
    { 1, "pbm",   "image/x-portable-bitmap" },
    { 1, "pdb",   "chemical/x-pdb" },
    { 1, "pdf",   "application/pdf" },
    { 1, "pgm",   "image/x-portable-graymap" },
    { 1, "pgn",   "application/x-chess-pgn" },
    { 2, "phtml", "text/html" },
    { 0, "png",   "image/png" },
    { 1, "pnm",   "image/x-portable-anymap" },
    { 1, "ppm",   "image/x-portable-pixmap" },
    { 1, "ppt",   "application/vnd.ms-powerpoint" },
    { 2, "ps\0",  "application/postscript" },
    { 0, "qt\0",  "video/quicktime" },
    { 0, "ra\0",  "audio/x-pn-realaudio" },
    { 1, "ram",   "audio/x-pn-realaudio" },
    { 0, "rar",   "application/x-rar" },
    { 1, "ras",   "image/x-cmu-raster" },
    { 2, "rdf",   "application/rdf+xml" },
    { 1, "rgb",   "image/x-rgb" },
    { 0, "rm\0",  "application/vnd.rn-realmedia" },
    { 0, "rmvb",  "application/vnd.rn-realmedia" },
    { 1, "roff",  "application/x-troff" },
    { 2, "rtf",   "text/rtf" },
    { 2, "rtx",   "text/richtext" },
    { 2, "sgm",   "text/sgml" },
    { 2, "sgml",  "text/sgml" },
    { 2, "sh\0",  "application/x-sh" },
    { 2, "shar",  "application/x-shar" },
    { 2, "shtml", "text/html" },
    { 1, "silo",  "model/mesh" },
    { 1, "sit",   "application/x-stuffit" },
    { 1, "skd",   "application/x-koan" },
    { 1, "skm",   "application/x-koan" },
    { 1, "skp",   "application/x-koan" },
    { 1, "skt",   "application/x-koan" },
    { 1, "smi",   "application/smil" },
    { 1, "smil",  "application/smil" },
    { 1, "snd",   "audio/basic" },
    { 1, "so\0",  "application/octet-stream" },
    { 1, "spl",   "application/x-futuresplash" },
    { 1, "src",   "application/x-wais-source" },
    { 1, "sv4cpio","application/x-sv4cpio" },
    { 1, "sv4crc","application/x-sv4crc" },
    { 1, "svg",   "image/svg+xml" },
    { 1, "swf",   "application/x-shockwave-flash" },
    { 1, "t\0\0", "application/x-troff" },
    { 1, "tar",   "application/x-tar" },
    { 0, "tbz",   "application/x-bzip2" },
    { 0, "tbz2",  "application/x-bzip2" },
    { 1, "tcl",   "application/x-tcl" },
    { 1, "tex",   "application/x-tex" },
    { 1, "texi",  "application/x-texinfo" },
    { 1, "texinfo","application/x-texinfo" },
    { 0, "tgz",   "application/x-gzip" },
    { 0, "tz\0",  "application/x-compress" },
    { 0, "tif",   "image/tiff" },
    { 0, "tiff",  "image/tiff" },
    { 1, "tr\0",  "application/x-troff" },
    { 2, "tsv",   "text/tab-separated-values" },
    { 2, "txt",   "text/plain" },
    { 1, "ustar", "application/x-ustar" },
    { 2, "vbs",   "text/plain" },
    { 1, "vcd",   "application/x-cdlink" },
    { 0, "vob",   "video/mpeg" },
    { 1, "vrml",  "model/vrml" },
    { 1, "vxml",  "application/voicexml+xml" },
    { 1, "wav",   "audio/x-wav" },
    { 1, "wbmp",  "image/vnd.wap.wbmp" },
    { 1, "wbxml", "application/vnd.wap.wbxml" },
    { 0, "wma",   "audio/x-ms-wma" },
    { 2, "wml",   "text/vnd.wap.wml" },
    { 1, "wmlc",  "application/vnd.wap.wmlc" },
    { 2, "wmls",  "text/vnd.wap.wmlscript" },
    { 1, "wmlsc", "application/vnd.wap.wmlscriptc" },
    { 0, "wmv",   "video/x-ms-wmv" },
    { 1, "wrl",   "model/vrml" },
    { 2, "xbm",   "image/x-xbitmap" },
    { 2, "xht",   "application/xhtml+xml" },
    { 2, "xhtml", "application/xhtml+xml" },
    { 2, "xls",   "application/vnd.ms-excel" },
    { 2, "xml",   "application/xml" },
    { 2, "xpm",   "image/x-xpixmap" },
    { 2, "xsl",   "application/xml" },
    { 2, "xslt",  "application/xslt+xml" },
    { 2, "xul",   "application/vnd.mozilla.xul+xml" },
    { 1, "xwd",   "image/x-xwindowdump" },
    { 1, "xyz",   "chemical/x-xyz" },
    { 0, "z\0\0", "application/x-compress" },
    { 0, "zip",   "application/zip" },
};


extern int CheckZip(const char* );

int CheckZip(const char* content_type)
{
    int content_num=sizeof(proxy_mimetypes)/sizeof(proxy_mrec);
    for(int i=0;i<content_num;i++)
    {
        if(strncasecmp(content_type,proxy_mimetypes[i].mime,strlen(proxy_mimetypes[i].mime))==0)
        {
            if(proxy_mimetypes[i].gzippable==0)
            {
                return 0;
            }
            else
                return 1;
        }    
    }
    return 0;
}


static int last_mod_cmp(const char* src_filepath, const char* dst_filepath)
{
    struct stat stBuf1, stBuf2;
    if(stat(src_filepath, &stBuf1) == 0 && stat(dst_filepath, &stBuf2) == 0)
    {
        //compare the last modified time
        if(stBuf1.st_mtime == stBuf2.st_mtime)
            return 0;
    }
    
    return -1;
}

int get_mime_type(const char* filename,  char* mime, int& zip)
{
    const char* tempext = filename;
    const char* ext = NULL;
   char gzipfilename[1024];
	
    while((tempext = strstr(tempext, ".")))
    	{
    	    ext = tempext++;
    	}
	
    if(!ext)
		return -1;
		

	 sprintf(gzipfilename, "%s.tgz", filename);
	 if(last_mod_cmp(gzipfilename,filename )==0)
	 	{
	 	    zip = 1;
	 	}

	  ext++;
	
    for(int i=0; i<(int)(sizeof(proxy_mimetypes)/sizeof(*proxy_mimetypes)); i++)
    {
        if(strcmp(ext, proxy_mimetypes[i].ext) == 0)
        {
          
            strcpy(mime,proxy_mimetypes[i].mime);

            return 0;
        }
    }
    
    return -1;
}


TCGIControl::TCGIControl (void) : 
_stCgiDics (NULL),
_pCgiSwitch (NULL)
{
    _support_prefix = 0;    
}

TCGIControl::~TCGIControl (void)
{
    FREE_CLEAR(_stCgiList);
    
    CSingleton<TCGIInfo>::Destroy();
}

TCGIControl* TCGIControl::Instance (void)
{
    return CSingleton<TCGIControl>::Instance ();
}

void TCGIControl::Destroy (void)
{
    return CSingleton<TCGIControl>::Destroy ();
}

int TCGIControl::open (const char* xmlfile)
{
    CMarkupSTL  markup;

	//this is important
	_nCgiCount=0;

    if(NULL == _stCgiDics)
    {
        _stCgiDics = CSingleton<TCGIInfoDic>::Instance ();
        if (NULL == _stCgiDics)
        {
            log_boot ("create cgi info dictionary failed.");
            return -1;
        }
    }
    else
    {
        _stCgiDics->release_items();
    }
    
    //init cgi info dictionary for no case
    if (_stCgiDics->init_root(1) != 0)
    {
        log_boot ("init url dictionary failed.");
        return -1;
    }
    
    if(NULL == _stCgiList)
    {
        //create cgi info list
        _stCgiList = (TCGIInfo*) MALLOC (MAX_CGI_COUNT * sizeof(TCGIInfo));
        if (NULL == _stCgiList)
        {
            log_boot ("create cgi info list failed, msg[%s]", strerror(errno));
            return -1;
        }
    }

    memset (_stCgiList, 0x00, MAX_CGI_COUNT * sizeof(TCGIInfo));

	if(!markup.Load(xmlfile))
	{	
		log_boot ("Load xml %s failed", xmlfile);
		return -1;
	}

    if(!markup.FindElem("SYSTEM"))
	{
		log_boot ("Can not FindElem [SYSTEM] in xml %s failed\n", xmlfile);
		return -1;
	}

    if (!markup.IntoElem())
    {
        log_boot ("invoke IntoElem() failed.");
        return -1;
    } 
    
    if(!markup.FindElem("ModuleList"))
	{
		log_boot ("Can not FindElem [ModuleList] in xml %s failed\n", xmlfile);
		return -1;
	}
    
    markup.IntoElem();

    while(markup.FindElem("Section"))
    {
        string szHost = markup.GetAttrib("VirtuelHost");
        string szPath = markup.GetAttrib("ServerPath");
        string szlocation = markup.GetAttrib("Location");
	 string section_info500  = markup.GetAttrib("RspFile");
	 string static_root = markup.GetAttrib("DocRoot");
	 string default_cgi = markup.GetAttrib("DefaultCGI");

	 //load the VirtuelHost's default cgi	
//	 printf("%s  %s \n",szHost.c_str(),default_cgi.c_str());
	 if(szHost.size()>0&&default_cgi.size()>0){
	 _mDefault_cginame.insert(make_pair(szHost, default_cgi));
	 }

        while (markup.FindChildElem("Module"))
        {
            memset((void*)&_stCgiList[_nCgiCount],0,sizeof(TCGIInfo));
            string szName     =   markup.GetChildAttrib("ModName");
            string szState    =   markup.GetChildAttrib("State");
            string szType     =   markup.GetChildAttrib("RunType");
	     string module_info500 = markup.GetAttrib("RspFile");
            string dynamic_gzip=markup.GetChildAttrib("Dynamic_GZip");
            string gzip_inf=markup.GetChildAttrib("Dynamic_GZip_Inf");

            if((szState.length() > 0 && strcasecmp(szState.c_str(), "disable") == 0 ) 
                    || 0 == szName.length())
            {
                //skip not enable & cgi_name is null
                log_boot ("cgi name[%s] is disabled or cgi name is null.", szName.c_str());
                continue;
            }

            if(NULL != strstr(szName.c_str(), "proxy_module"))
                continue;

	    if(module_info500.length() == 0)
			module_info500 = section_info500;			

            strncpy (_stCgiList[_nCgiCount]._szCgiName, szName.c_str(), MAX_PATH_LEN - 1);

            for(int i = 0; i < (int)szName.length(); i++)
            {
                if(_stCgiList[_nCgiCount]._szCgiName[i] == '/')
                {
                    _stCgiList[_nCgiCount]._szCgiName[i] = '_';
                }
            }
                
		

            snprintf(_stCgiList[_nCgiCount]._szUnixPath, MAX_PATH_LEN - 1, "%s", szName.c_str());
            _stCgiList[_nCgiCount]._nPathLen = szName.length();
            _stCgiList[_nCgiCount]._nIndex = _nCgiCount;

            if(0 == strcasecmp(szType.c_str(), "static"))
                _stCgiList[_nCgiCount]._bStatic = true;
            else
                _stCgiList[_nCgiCount]._bStatic = false;

            if(dynamic_gzip=="disable")
                _stCgiList[_nCgiCount]._gzip_enable=false;
            else if(dynamic_gzip=="enable")
            {
                _stCgiList[_nCgiCount]._gzip_enable=true;
            }
            else if(TGlobal::_gzip_enable==true)
                _stCgiList[_nCgiCount]._gzip_enable=true;
            else
                _stCgiList[_nCgiCount]._gzip_enable=false;
            
            if(gzip_inf=="")
                _stCgiList[_nCgiCount]._gzip_inf=TGlobal::_gzip_inf;
            else
            {
                _stCgiList[_nCgiCount]._gzip_inf=atoi(gzip_inf.c_str());
                if(_stCgiList[_nCgiCount]._gzip_inf<0)
                    _stCgiList[_nCgiCount]._gzip_inf=0;
			}




			if(szPath.length() > 0)
					strncpy(_stCgiList[_nCgiCount]._szSvrPath, szPath.c_str(), MAX_PATH_LEN - 1);
			if(szlocation.length() > 0)
					strncpy(_stCgiList[_nCgiCount].location, szlocation.c_str(), MAX_PATH_LEN - 1);
			if(module_info500.length() > 0)
			{
					log_info("RspFile[%s]  process", module_info500.c_str());
					if(_stCgiList[_nCgiCount].static500)
					{
							log_info("RspFile[%s]  static500[%x]",_stCgiList[_nCgiCount].static500,_stCgiList[_nCgiCount].static500_len);
							delete _stCgiList[_nCgiCount].static500;
							_stCgiList[_nCgiCount].static500 = NULL;
							_stCgiList[_nCgiCount].static500_len = 0;
							_stCgiList[_nCgiCount].gzip = 0;
							_stCgiList[_nCgiCount].mime[0] = 0;


					}
					char filepath[1024];
					//char gzipfilepath[1024];

					sprintf(filepath, "%s/%s",static_root.c_str(), module_info500.c_str());
					log_info("RspFile Full path[%s]  ", filepath);

					get_mime_type(filepath,_stCgiList[_nCgiCount].mime,_stCgiList[_nCgiCount].gzip);

					if(_stCgiList[_nCgiCount].gzip)
							sprintf(filepath, "%s/%s.tgz",static_root.c_str(), module_info500.c_str());


					struct stat sBuf;
					//get the information for the request file
					if(stat(filepath, &sBuf) == 0)
					{
							if(sBuf.st_size > 0)                      
							{
									_stCgiList[_nCgiCount].static500 =  new char[sBuf.st_size+1];
                                    if( _stCgiList[_nCgiCount].static500 == NULL )
                                    {
                                        return -1;
                                    }
									memset(_stCgiList[_nCgiCount].static500, 0, sBuf.st_size+1);
							}

							if(_stCgiList[_nCgiCount].static500)
							{
									FILE* file = fopen(filepath, "r");
									if(file)
									{
											_stCgiList[_nCgiCount].static500_len =  fread(_stCgiList[_nCgiCount].static500, 1,sBuf.st_size,file);
											fclose(file);
											log_info("rsp500 info zip[%d] mime[%s]  infolen[%d]",_stCgiList[_nCgiCount].gzip,_stCgiList[_nCgiCount].mime,_stCgiList[_nCgiCount].static500_len);

									}
									else
									{
											log_error("500 error info--->open failed:%s", filepath);
									}
							}



					}		
					else
					{
							log_error("500 error info--->stat file size failed:%s", filepath);
					}

			}

			stringstream ssHost(szHost);
			while(true)
			{
					string szToken;   
					getline(ssHost, szToken, ',');   
					if(ssHost.fail()) 
							break;

					TGlobal::trim(szToken);

					_stCgiList[_nCgiCount]._vHostList.push_back(szToken);;
			}

			int ret = _stCgiDics->add_key(_stCgiList[_nCgiCount]._szUnixPath, _stCgiList[_nCgiCount]._nPathLen, &(_stCgiList[_nCgiCount]));

			if (0 != ret)
			{
					log_boot ("insert a TCGIOperInfo object failed, cgipath[%s], cginame[%s], count : %d, err: %m",
									_stCgiList[_nCgiCount]._szUnixPath,
									_stCgiList[_nCgiCount]._szCgiName,
									_nCgiCount);
					log_error ("insert a TCGIOperInfo object failed, cgipath[%s], cginame[%s], count : %d, err: %m",
									_stCgiList[_nCgiCount]._szUnixPath,
									_stCgiList[_nCgiCount]._szCgiName,
									_nCgiCount);

					continue;

					//return -1;
			}

			_nCgiCount++;
		}
	}

	markup.OutOfElem();

	if (_nCgiCount <= 0)
	{
			log_boot ("valid cgi info no found, cgi count[%d]", _nCgiCount);
			return -1;
	}

	if(!markup.FindElem("Switch"))
	{
			log_boot ("Can not FindElem [Switch] in xml %s failed\n", xmlfile);
			return -1;
	}

	//get cgi index
	int nSwitch = atoi(markup.GetAttrib("Index").c_str());  




	if (nSwitch < 0)
	{
			log_warning("cgi switch index is closed!!!");

			while(markup.FindChildElem("Item"))
			{
					string szCond = markup.GetChildAttrib("Condition");
					int nItem = atoi(markup.GetChildAttrib("Index").c_str());
					//string cgipath = markup.GetChildAttrib("Index");

					if(szCond.length() > 0 && nItem >=0 && nItem < _nCgiCount)
					{
							_mSwitchList.insert(make_pair(szCond, nItem));
					}
			}
	}
	else
	{
			if (nSwitch >= _nCgiCount)
			{
					log_boot ("cgi switch index [%d] is invalid, cgi count[%d]!!!", nSwitch, _nCgiCount);
					return -1;
			}

			_pCgiSwitch = &_stCgiList[nSwitch];
			//_stCgiDics->search_ncase_key (cgi_path, len, &pCGIInfo);

			log_boot ("cgi switch index [%d] is open!!!", nSwitch);

	}

	CMarkupSTL markup1;
	if(!markup1.Load(xmlfile))
	{	
			log_boot ("Load xml %s failed", xmlfile);
			return -1;
	}
	if(!markup1.FindElem("SYSTEM"))
	{
			log_boot ("Can not FindElem [SYSTEM] in xml %s failed\n", xmlfile);
			return -1;
	}

	if (!markup1.IntoElem())
	{
			log_boot ("invoke IntoElem() failed.");
			return -1;
	} 

	if(!markup1.FindElem("Switch"))
	{
			log_boot ("sccond find: Can not FindElem [Switch] in xml %s failed\n", xmlfile);
			return -1;
	}

	string switch_cgipath = markup1.GetAttrib("cginame");
	string switch_pri = markup1.GetAttrib("pri_first");
	string prefix_mach = markup1.GetAttrib("prefix_mach");
	if(prefix_mach.length() > 0)
	{
			_support_prefix = atoi(prefix_mach.c_str());
	}
	else
			_support_prefix = 0;

	if(switch_pri.length() > 0)
	{
			if(atoi(switch_pri.c_str()))
					_mSwitchList_cginame.insert(make_pair("pri_first", "first"));		   
	}

	if(switch_cgipath.length() > 0)
	{
			log_warning("cginame switch index is open!!!");
			_stCgiDics->search_ncase_key(switch_cgipath.c_str(), switch_cgipath.length(), &_pCgiSwitch);
	}
	else
	{
			log_warning("cginame switch index is closed!!!");

			while(markup1.FindChildElem("Item"))
			{
					string szCond = markup1.GetChildAttrib("Condition");
					// int nItem = atoi(markup.GetChildAttrib("Index").c_str());
					string cgipath = markup1.GetChildAttrib("cginame");

					if(szCond.length() > 0 && cgipath.length() >0 )
					{
							_mSwitchList_cginame.insert(make_pair(szCond, cgipath));
					}
			}

	}

	return 0;
}

TCGIInfo* TCGIControl::prefix_mach(const char* url, int len)
{

		log_info("prefix_mach[%d]-->switch-->%s, %d",_support_prefix,  url,len);
		if(!_support_prefix)
				return NULL;

		TCGIInfo* pCGIInfo = NULL;	
		map<string, string>::iterator iter = _mSwitchList_cginame.begin();
		map<string, string>::iterator dst_iter;
		int  mach_len = 0;
		while(iter != _mSwitchList_cginame.end())
		{
				const char* pstr = iter->first.c_str();
				//const char* pcondition = NULL;
				pstr = strstr(url, pstr);

				if((pstr==url) && ((unsigned)mach_len < iter->first.length()))
				{
						mach_len = iter->first.length();
						dst_iter = iter;
				}
				iter++;
		}

		log_info("prefix_mach[%d]-->switch-->mach_len[%d]",_support_prefix, mach_len);

		if(mach_len > 0)
		{
				log_info("prefix_mach-->switch-->%s, %d", url,len);
				_stCgiDics->search_ncase_key(dst_iter->second.c_str(),dst_iter->second.length(),&pCGIInfo);	    	   
		}	 	    
		return pCGIInfo;

}

TCGIInfo* TCGIControl::find_cgi(const char* cgi_path, int len)
{
		TCGIInfo* pCGIInfo = NULL;

		map<string, string>::iterator iter = _mSwitchList_cginame.find("pri_first");

		if(iter != _mSwitchList_cginame.end())
		{
				int t_len = len;
				char* purlend = strstr((char *)cgi_path," HTTP/1.1");
				if(!purlend)
				{
						purlend = strstr((char *)cgi_path," HTTP/1.0");
				}
				if(!purlend)
				{
						purlend = strstr((char *)cgi_path," HTTP/0.9");
				}

				if(purlend)
				{
						if((purlend-cgi_path) < len)
								t_len = purlend-cgi_path;
				}

				string szUrl(cgi_path, 0, t_len); 
				log_info("find_cgi_ext-->switch--> %s", szUrl.c_str());
				iter = _mSwitchList_cginame.find(szUrl);  


				if(iter != _mSwitchList_cginame.end())
				{
						log_info("find_cgi-->switch-->%s, %s", szUrl.c_str(),iter->second.c_str());
						_stCgiDics->search_ncase_key(iter->second.c_str(),iter->second.length(),&pCGIInfo);	    	   
				}

				if(!pCGIInfo)
				{
						pCGIInfo = prefix_mach(szUrl.c_str(), szUrl.length());
				}
				if(pCGIInfo && pCGIInfo->_bStatic)
				{
						pCGIInfo = NULL;
						return NULL;

				}

				if(pCGIInfo)
						return pCGIInfo;
		}


		_stCgiDics->search_ncase_key (cgi_path, len, &pCGIInfo);

		return pCGIInfo;
}

TCGIInfo* TCGIControl::find_cgi_ext(const char* url, int len)
{
		int t_len = len;
		char* purlend = strstr((char *)url," HTTP/1.1");

		if(!purlend)
		{
				purlend = strstr((char *)url," HTTP/1.0");
		}
		if(!purlend)
		{
				purlend = strstr((char *)url," HTTP/0.9");
		}
		if(purlend)
		{
				if((purlend-url) < len)
						t_len = purlend-url;
		}		

		string szUrl(url, 0, t_len); 

		map<string, int>::iterator iter = _mSwitchList.find(szUrl);

		if(iter == _mSwitchList.end())
		{
				log_info("find_cgi_ext-->switch--> %s", szUrl.c_str());
				map<string, string>::iterator iter1 = _mSwitchList_cginame.find(szUrl);
				TCGIInfo* pCGIInfo = NULL;


				if(iter1 == _mSwitchList_cginame.end())
				{

						pCGIInfo = prefix_mach(szUrl.c_str(), szUrl.length());

						if(!pCGIInfo)
						{

								log_info("find_cgi_ext-->switch--> %s", "default");
								iter1 = _mSwitchList_cginame.find("default");
						}
				}
				if(!pCGIInfo && (iter1 != _mSwitchList_cginame.end()))
				{
						log_info("find_cgi_ext-->switch-->%s", iter1->second.c_str());
						_stCgiDics->search_ncase_key (iter1->second.c_str(), iter1->second.length(), &pCGIInfo);
				}




				if(pCGIInfo && pCGIInfo->_bStatic)
				{
						pCGIInfo = NULL;
						return NULL;

				}	      

				return pCGIInfo;
		}

		log_info("find_cgi_ext-->switch--> %s index[%d]", szUrl.c_str(), iter->second);
		//TCGIInfo* pCGIInfo = NULL;

		//_stCgiDics->search_ncase_key (iter->second, len, &pCGIInfo);

		//   return pCGIInfo;
		return  &(_stCgiList[iter->second]);
}

HTTP_SVR_NS_END

